package ricky.scene
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	import ricky.events.CameraEvent;
	
	[Event(name="camera_move", type="ricky.events.CameraEvent")]
	[Event(name="camera_grid_change", type="ricky.events.CameraEvent")]
	[Event(name="camera_resize", type="ricky.events.CameraEvent")]
	/**
	 * 游戏世界中得镜头
	 */
	public class Camera extends Rectangle  implements IEventDispatcher
	{
		/**
		 * x顶点,y顶点.
		 * width镜头宽
		 * height镜头高
		 */
		public function Camera(x:Number=0, y:Number=0, width:Number=0, height:Number=0)
		{
			super(x, y, width, height);
			this._offX=width/2;
			this._offY=height/2;
			cameraMoveEvent=new CameraEvent(CameraEvent.Camera_Move,this);
			cameraGridChangeEvent=new CameraEvent(CameraEvent.Camera_Grid_Change,this);
			dispatcher=new EventDispatcher();
		}
		
		/**
		 * 改变镜头大小
		 */
		public function resize(width:Number,height:Number,x:Number=NaN,y:Number=NaN):void
		{
			if(!isNaN(x))
				this.x=x;
			if(!isNaN(y))
				this.y=y;
			this.width=width;
			this.height=height;
			this._offX=width/2;
			this._offY=height/2;
			this.gridWidth=gridWidth;
			this.gridHeight=gridHeight;
			dispatcher.dispatchEvent(new CameraEvent(CameraEvent.Camera_Resize,this));
		}
		
		/**
		 * 镜头移动派发移
		 * 动事件
		 * 镜头顶点移动到x,y座标
		 */
		public function moving(x:Number,y:Number):void
		{
			
			if(x<0)
				x=0;
			if( y<0)
				y=0;
			
			if(x>_maxWidth-this.width)
				x=_maxWidth-this.width;
			
			if(y>_maxHeight-this.height)
				y=_maxHeight-this.height;
			
			
			this.x=x;
			this.y=y;
			
			setGridXY();

			if(_lastGx!=_currGx || _lastGy!=_currGy)
			{
				dispatcher.dispatchEvent(cameraGridChangeEvent);
			}
			_lastGx=_currGx;_lastGy=_currGy;
			
			dispatcher.dispatchEvent(cameraMoveEvent);
		}
		
		/**
		 * 以镜头偏移点为中心点的移动
		 */
		public function offMoving(x:Number,y:Number):void
		{
			var x1:Number,y1:Number;
			x1=x-_offX;
			y1=y-_offY;
			moving(x1,y1);
		}
		
		/**
		 * 以镜头偏移点为中心点的移动
		 */
		public function offMoveTo(x:Number,y:Number):void
		{
			var x1:Number,y1:Number;
			x1=x-_offX;
			y1=y-_offY;
			moveTo(x1,y1);
		}
		
		/**
		 * 镜头顶点 自动移动到目标点
		 */
		public function moveTo(x:Number,y:Number):void
		{
			_targetx=x;
			_targety=y;
			
			lastFrame=getTimer()/ 1000;

			var dx:Number = _targetx - this.x;
			var dy:Number = _targety - this.y;
			var angle:Number = Math.atan2(dy, dx);
			vx = Math.cos(angle) * speed;
			vy = Math.sin(angle) * speed;
			
			if(!_timer)
				_timer=new Timer(10);
			if(!_timer.hasEventListener(TimerEvent.TIMER))
				_timer.addEventListener(TimerEvent.TIMER,onTimer);
			if(!_timer.running)
				_timer.start();
			
		}
		
		/**
		 * 设置left-top格子坐标
		 */
		private function setGridXY():void
		{
			_currGx=Math.floor(x/this._gridWidth);
			_currGy=Math.floor(y/this._gridHeight);
		}
		
		/////////////////////////////////////////////////////////////////////////////////
		
		protected function onTimer(e:TimerEvent):void
		{
			if (Math.abs(_targetx - x)<=10 && Math.abs(_targety - y)<=10)
			{
				//停止
				moving(x,y);
				_timer.stop();
				return;
			}
			else
			{
				var dt:Number=getTimer()/ 1000 - lastFrame;//Game.fpsdt;
				var v1:Number = vx * dt;
				var v2:Number = vy * dt;
				x = Math.abs(_targetx - x) <= Math.abs(v1)?_targetx:v1 + x;
				y = Math.abs(_targety - y) <= Math.abs(v2)?_targety:v2 + y;
				lastFrame =getTimer()/ 1000;
				moving(x,y);
			}
		}
		
		////////////////////////////////////////////////
		//自定义属性
		/////////////////////////////////////////////////
		
		/**
		 * x 横向格子数目
		 */
		public function get xGridCount():int
		{
			return Math.ceil(maxWidth/gridWidth);
		}
		
		/**
		 * y 纵向格子数目
		 */
		public function get yGridCount():int
		{
			return Math.ceil(maxHeight/gridHeight);
		}
		
			
		/**
		 * 地图网格高度
		 */
		public function get gridHeight():Number
		{
			return _gridHeight;
		}
		
		public function set gridHeight(value:Number):void
		{
			_gridHeight = value;
			this._gridBufferHeight=Math.ceil(height/_gridHeight);
		}
		
		/**
		 * 地图网格的宽度
		 */
		public function get gridWidth():Number
		{
			return _gridWidth;
		}
		
		
		public function set gridWidth(value:Number):void
		{
			_gridWidth = value;
			_gridBufferWidth=Math.ceil(width/_gridWidth);
		}
		
		/**
		 * 最大像素高度
		 */
		public function get maxHeight():Number
		{
			return _maxHeight;
		}
		
		/**
		 * @private
		 */
		public function set maxHeight(value:Number):void
		{
			_maxHeight = value;
		}
		
		/**
		 * 最大像素宽度
		 */
		public function get maxWidth():Number
		{
			return _maxWidth;
		}
		
		/**
		 * @private
		 */
		public function set maxWidth(value:Number):void
		{
			_maxWidth = value;
		}
		
		/**
		 * 镜头的移动速度
		 */
		public function get speed():Number
		{
			return _speed;
		}
		
		public function set speed(value:Number):void
		{
			_speed = value;
		}
		
		private var lastFrame:Number,_speed:Number=50;
		private var _targetx:Number,_targety:Number
		private var vx:Number,vy:Number;
		
		private var _timer:Timer;
		
		private var _offX:Number=0,_offY:Number=0;
		private var _maxWidth:Number,_maxHeight:Number;
		private var _gridWidth:Number=30,_gridHeight:Number=40,_gridBufferWidth:int,_gridBufferHeight:int;		
		private var _currGx:int,_currGy:int,_lastGx:int=-1,_lastGy:int=-1;
		
		/**
		 * 镜头移动事件
		 */
		private var cameraMoveEvent:CameraEvent,cameraGridChangeEvent:CameraEvent;
		
		//////////////////////////////////
		// 接口实现
		/////////////////////////////////////
		
		
		private var dispatcher:EventDispatcher;

		/**
		 * 	将事件调度到事件流中。 
		 */
		public function dispatchEvent(event:Event):Boolean
		{
			return dispatcher.dispatchEvent(event)
		}
		
		/**
		 * 使用 EventDispatcher 对象注册事件侦听器对象，以使侦听器能够接收事件通知。 IEventDispatcher 
		 * dispatchEvent(event:Event):Boolean 
		 * 将事件调度到事件流中。  IEventDispatcher 
		 */
		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
		{
			dispatcher.addEventListener(type,listener,useCapture, priority, useWeakReference);
		}
		/**
		 * 	检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器。 IEventDispatcher 
		 */
		public function hasEventListener(type :String):Boolean
		{
			return dispatcher.hasEventListener(type);
		}
		
		/**
		 * 	从 EventDispatcher 对象中删除侦听器。 IEventDispatcher 
		 */
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
		{
			dispatcher.removeEventListener(type, listener, useCapture);
		}
		
		/**
		 * 	检查是否用此 EventDispatcher 对象或其任何始祖为指定事件类型注册了事件侦听器。 
		 */
		public function willTrigger(type :String):Boolean
		{
			return dispatcher.willTrigger(type);
		}

		/**
		 * x轴偏移量
		 */
		public function get offX():Number
		{
			return _offX;
		}

		/**
		 * @private
		 */
		public function set offX(value:Number):void
		{
			_offX = value;
		}

		/**
		 * y轴偏移量
		 */
		public function get offY():Number
		{
			return _offY;
		}

		/**
		 * @private
		 */
		public function set offY(value:Number):void
		{
			_offY = value;
		}
		
		/**
		 * left-top 的格子y坐标
		 */
		public function get gridY():int
		{
			return _currGy;
		}
		
		/**
		 * left-top 的格子X坐标
		 */
		public function get gridX():int
		{
			return _currGx;
		}

		public function get gridBufferWidth():int
		{
			return _gridBufferWidth;
		}

		public function set gridBufferWidth(value:int):void
		{
			_gridBufferWidth = value;
		}

		public function get gridBufferHeight():int
		{
			return _gridBufferHeight;
		}

		public function set gridBufferHeight(value:int):void
		{
			_gridBufferHeight = value;
		}

		
	}
}